<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Api\ApiController;
use App\Http\Exports\OrderExport;
use App\Http\Exports\PartnerExport;
use App\Http\Exports\StaffExport;
use App\Http\Forms\ApplicationForm;
use App\Http\Forms\MemberForm;
use App\Http\Forms\StaffForm;
use App\Http\Forms\UserForm;
use App\Http\Forms\UserMemberForm;
use App\Library\OSS;
use App\Modules\Shop\Shop;
use App\Modules\User\Manager;
use App\Modules\User\Models\Account;
use App\Modules\User\Models\Admin;
use App\Modules\User\Models\ApplyPartner;
use App\Modules\User\Models\applyPartners;
use App\Modules\User\Models\Member;
use App\Modules\User\Models\OldUser;
use App\Modules\User\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use phpDocumentor\Reflection\Types\Collection;
use Illuminate\Support\Facades\URL;

class UserController extends ApiController
{
    public function index(Request $request)
    {
        $this->authorize('user');
        $search = $request->input('search');
        $searchReferrer = $request->input('searchReferrer');
        $level = $request->input('level', "0");
        $userId = $request->input('user_id');
        $this->authorize("user-level{$level}");

        $query = User::query();
        if (!empty($userId)) {
            $query->where('id', $userId);
        } else {
            if (!empty($search)) {
                $query->where(function ($q) use ($search) {
                    return $q->where('nickname', 'like', "%" . $search . "%")
                        ->orWhere('mobile', 'like', "%" . $search . "%")
                        ->orWhere('name', 'like', "%" . $search . "%");
                });
            }
            if ($level != "") {
                $query->where('level', $level);
            }
            if (!empty($searchReferrer)) {
                $personal = User::query()
                    ->where('name', $searchReferrer)
                    ->get();
                $personalIds = [0];
                if (!is_null($personal)) {
                    $personalIds = $personal->pluck('id')->all();
                }
                $query->whereIn('personal_id', $personalIds);
            }
        }

        $count = $query->count();
        $data = $query->orderBy('created_at', 'desc')
            ->paginate(20);
        $referrer = User::query()->whereIn('id', array_merge($data->pluck('referrer_id')->all(), $data->pluck('personal_id')->all()))->get()->keyBy('id');
        $shop = \App\Modules\Shop\Manager::getShop();
        $sidebar = $level == 0 ? 'index' : 'index' . $level;
        return view('user.index', compact('data', 'sidebar', 'count', 'data', 'search', 'level', 'referrer', 'shop', 'searchReferrer'));
    }

    // 全部用户
    public function all(Request $request)
    {
        // $this->authorize('user-all');
        $search = $request->input('search');
        $searchReferrer = $request->input('searchReferrer');
        $level = $request->input('level', '');
        $userId = $request->input('user_id');
        // $this->authorize("user-level{$level}");

        $query = User::query();
        if (!empty($userId)) {
            $query->where('id', $userId);
        } else {
            if (!empty($search)) {
                $query->where(function ($q) use ($search) {
                    return $q->where('nickname', 'like', "%" . $search . "%")
                        ->orWhere('mobile', 'like', "%" . $search . "%")
                        ->orWhere('name', 'like', "%" . $search . "%");
                });
            }
            // if ($level != "") {
            //     $query->where('level', $level);
            // }
            if (!empty($searchReferrer)) {
                $personal = User::query()
                    ->where('name', $searchReferrer)
                    ->get();
                $personalIds = [0];
                if (!is_null($personal)) {
                    $personalIds = $personal->pluck('id')->all();
                }
                $query->whereIn('personal_id', $personalIds);
            }
        }

        $count = $query->count();
        $data = $query->orderBy('created_at', 'desc')
            ->paginate(20);
        $referrer = User::query()->whereIn('id', array_merge($data->pluck('referrer_id')->all(), $data->pluck('personal_id')->all()))->get()->keyBy('id');
        $shop = \App\Modules\Shop\Manager::getShop();
        $sidebar = 'all';
        return view('user.all', compact('data', 'sidebar', 'count', 'data', 'search', 'level', 'referrer', 'shop', 'searchReferrer'));
    }

    public function exportPartner(Request $request)
    {

        $search = $request->input('search');
        $searchReferrer = $request->input('searchReferrer');
        $level = $request->input('level');
        $file = (new PartnerExport("名单.xlsx"))->instance();
        $this->authorize("user-level{$level}-export");
        User::query()
            ->leftJoin('users as b', 'users.referrer_id', '=', 'b.id')
            ->leftJoin('users as c', 'users.personal_id', '=', 'c.id')
            ->when(!empty($level), function ($query) use ($level) {
                return $query->where('users.level', $level);
            })
            ->when(!is_null($level), function ($query) use ($level) {
                return $query->where('users.level', $level);
            })
            ->when(!empty($searchReferrer), function ($query) use ($searchReferrer) {
                return $query->where('c.name', $searchReferrer);
            })
            ->when(!empty($search), function ($query) use ($search) {
                return $query->where('users.nickname', 'like', "%" . $search . "%")
                    ->orWhere('users.mobile', 'like', "%" . $search . "%")
                    ->orWhere('users.name', 'like', "%" . $search . "%");
            })
            ->orderBy('users.created_at', 'desc')
            ->select("users.*", "b.name as referrer_name", "b.level as referrer_level", "c.name as personal_name")
            ->chunk(500, function ($item) use ($file) {
                $tmp = $item->map(function ($item2) {
                    $nickname = "";
                    $pattern = '/[\x{4e00}-\x{9fa5}a-zA-Z0-9_]/u';
                    preg_match_all($pattern, $item2->nickname, $nickname);
                    $nickname = join('', $nickname[0]);
                    return [
                        $item2->name,
                        $nickname,
                        $item2->mobile,
                        $item2->referrer_name,
                        User::$levelShow[$item2->referrer_level] ?? "",
                        $item2->created_at,
                        $item2->last_time,
                        $item2->personal_name,
                    ];
                });
                $file->addData($tmp->all());
            });
        return $file->downLoad();
    }

    public function editInfo($id, Request $request)
    {
        $level = $request->input('level');
        $this->authorize("user-level{$level}-edit");
        $user = User::query()->find($id);
        $form = $this->form(UserForm::class, [
            'method' => "POST",
            'url' => route('admin.user.update', ['id' => $id, 'level' => $level]),
            'model' => $user,
        ]);
        $sidebar = $level == 0 ? 'index' : 'index' . $level;
        $flag = 'user';//用于区分表单页面的js
        session()->put('url.intended', url()->previous());
        return view('user.form', compact('sidebar', 'form', 'flag'));
    }

    public function updateInfo($id, Request $request)
    {
        $level = $request->input('level');
        $this->authorize("user-level{$level}-edit");
        $form = $this->form(UserForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        $user = User::query()
            ->where('id', "!=", $id)
            ->where('mobile', $data['mobile'])
            ->first();
        if (!is_null($user)) {
            return redirect()->back()->with('warning', "手机号已经注册")->withInput();
        }
        User::query()
            ->where('id', $id)
            ->update($data);
        $apply = ApplyPartner::query()
            ->where('user_id', $id)
            ->orderBy('created_at', 'desc')
            ->first();
        if (!is_null($apply)) {
            $apply->update(['name' => $data['name']]);
        }

        $flag = 'user';//用于区分表单页面的js
        return redirect()->intended();
        // return redirect()->route('admin.user.index', ['level' => $level]);
    }

    public function getStaff(Request $request)
    {
        $this->authorize('user-level3');
        $search = $request->input('search');
        $searchShop = $request->input('searchShop');
        $export = $request->input('export', 0);

        $query = User::query()
            ->when(!empty($searchShop), function ($query) use ($searchShop) {
                $query->whereExists(function ($q) use ($searchShop) {
                    return $q->select(DB::raw(1))
                        ->from('shops')
                        ->whereRaw("(JSON_CONTAINS(users.shop_id, JSON_ARRAY(shops.id)) OR JSON_CONTAINS(users.shop_id, JSON_UNQUOTE(JSON_ARRAY(CONCAT(shops.id))))) AND (name like '%{$searchShop}%')");
                });
            })
            ->where('level', 3);
        if (!empty($search)) {
            $query->where(function ($q) use ($search) {
                return $q->where('users.nickname', 'like', "%" . $search . "%")
                    ->orWhere('users.mobile', 'like', "%" . $search . "%")
                    ->orWhere('users.name', 'like', "%" . $search . "%");
            });
        }
        $allShops = Shop::query()->get()->keyBy('id');
        if ($export) {
            $data = $query
                ->selectRaw('users.name, users.nickname, users.mobile, users.shop_id, users.employee_identity, users.position, users.invite_code')
                ->get()
                ->map(function ($item) use ($allShops) {
                    $shopName = "";
                    if (!empty($item->shop_id)) {
                        foreach ($item->shop_id as $value) {
                            $shop = $allShops->get($value);
                            if (!is_null($shop)) {
                                $shopName .= "," . $shop->name;
                            }
                        }
                    }
                    return [
                        $item->name,
                        $item->nickname,
                        $item->mobile,
                        ltrim($shopName, ","),
                        $item->employee_identity,
                        $item->position,
                        $item->invite_code,
                    ];
                });
            return (new StaffExport("员工名单.xlsx", $data->all()))->downLoad();
        }
        $count = $query->selectRaw('users.*')->count();
        $data = $query->paginate(20);
        $sidebar = 'staff';
        return view('user.staff', compact('data', 'sidebar', 'search', 'count', 'searchShop', 'allShops'));
    }

    public function createStaff()
    {

    }

    public function storeStaff()
    {

    }

    public function editStaff($id, Request $request)
    {
        $this->authorize('user-level3-edit');
        $user = User::query()->find($id);
        $shop = Shop::query()->get();
        $form = $this->form(StaffForm::class, [
            'method' => 'POST',
            'url' => route('admin.user.staff.update', ['id' => $id]),
            'model' => $user,
        ], [
            'shop' => $shop->pluck('name', 'id')->all(),
        ]);
        $sidebar = 'staff';
        $flag = 'staff';//用于区分表单页面的js
        session()->put('url.intended', url()->previous());
        return view('user.form', compact('form', 'sidebar', 'flag'));
    }

    public function updateStaff($id)
    {
        $this->authorize('user-level3-edit');
        $form = $this->form(StaffForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        $other = User::query()
            ->where('mobile', $data['mobile'])
            ->where('id', '!=', $id)
            ->first();
        if (!is_null($other)) {
            return redirect()->back()->with('warning', "手机号已经注册")->withInput();
        }
        $user = User::query()->find($id);
        $user->update([
            'mobile'             => $data['mobile'],
            'name'               => $data['name'],
            'employee_identity'  => $data['employee_identity'],
            'is_palm_management' => $data['is_palm_management'],
            'position'           => $data['position'],
            'shop_id'            => $data['shop_id'],
        ]);
        return redirect()->intended();
        // return redirect()->route('admin.user.staff');
    }

    public function oldUser()
    {
        $this->authorize('user-member');
        $data = OldUser::query()
            ->orderBy('updated_at', 'desc')
            ->paginate(20);
        $sidebar = 'old';
        return view('user.old', compact('data', 'sidebar'));
    }

    public function storeOld(Request $request)
    {
        $this->authorize('user-member');
        $mobile = $request->input('mobile');
        OldUser::query()
            ->updateOrCreate([
                'mobile' => $mobile,
            ]);
        return redirect()->route('admin.user.old');
    }

    public function delOld(Request $request)
    {
        $this->authorize('user-member');
        $mobile = $request->input('mobile');
        OldUser::query()->where('mobile', $mobile)->delete();
        return redirect()->route('admin.user.old');
    }


    public function updateLevel(Request $request)
    {
        $id = $request->input('id');
        $level = $request->input('level');
        $identity = $request->input('identity');
        $shopId = $request->input('shop_id');
        $position = $request->input('position');
        $isPalmManagement = $request->input('is_palm_management');

        $this->authorize("user-level{$level}-level");
        $user = User::query()
//            ->where('level', "!=", $level)
            ->where('id', $id)
            ->first();
        $oldLevel = $user->level;
        if (is_null($user)) {
            return redirect()->back();
        }
        if ($level > 1) {
            $user->update([
                'referrer_id' => $user->id,
                'level' => $level,
                'invite_code' => $level == 3 ? Manager::getInviteCode() : null,
                'employee_identity' => $level == 3 ? $identity : null,
                'shop_id' => $level == 3 ? $shopId : null,
                'position' => $level == 3 ? $position : null,
                'is_palm_management' => $level == 3 ? $isPalmManagement : 0,
            ]);
        } else {
            $user->update([
                'level' => $level,
                'invite_code' => $level == 3 ? Manager::getInviteCode() : null,
                'employee_identity' => $level == 3 ? $identity : null,
                'is_palm_management' => $level == 3 ? $isPalmManagement : 0,
            ]);
        }
        /**
         *  临洮：身份变动
         *  模板ID：hDnA8kROBLiW-iNKQHDxbD8U3Ul8gS-SrWPScmHUM40
         *  格式：
         * {{first.DATA}}
         * 变动前级别：{{keyword1.DATA}}
         * 变动后级别：{{keyword2.DATA}}
         * 时间：{{keyword3.DATA}}
         * {{remark.DATA}}
         */
        $sendData = [$user->openid,User::$levelShow[$oldLevel],User::$levelShow[$level],date("Y年m月d日 H时i分s秒")];
        sendMessage(31,$sendData);
        return redirect()->back();
    }

    public function updatePersonal(Request $request)
    {
        $this->authorize('user-edit-referrer');
        $id = $request->input('id');
        $personalId = $request->input('personal_id');
        User::query()
            ->where('id', $id)
            ->update([
                'personal_id' => $personalId,
            ]);

        $apply = ApplyPartner::query()
            ->where('user_id', $id)
            ->orderBy('created_at', 'desc')
            ->first();
        if (!is_null($apply)) {
            $apply->update([
                'personal_id' => $personalId,
            ]);
        }

        return redirect()->back();
    }

    public function updateReferrer(Request $request)
    {
        $this->authorize('user-edit-referrer');
        $id = $request->input('id');
        $referrerId = $request->input('referrer_id');
        User::query()
            ->where('id', $id)
            ->update([
                'referrer_id' => $referrerId,
            ]);
        return redirect()->back();
    }

    public function batchReferrer(Request $request)
    {
        $this->authorize('user-edit-referrer');
        $oldReferrerId = $request->input('old_personal_id');
        $newReferrerId = $request->input('new_personal_id');
        User::query()
            ->where('personal_id', $oldReferrerId)
            ->update([
                'personal_id' => $newReferrerId,
            ]);
        return redirect()->back();
    }

    public function createApplication(Request $request)
    {
        $this->authorize('user-apply-edit');
        $userId = $request->input('user_id');

        $sidebar = $request->input('sidebar', 'apply');
        $form = $this->form(ApplicationForm::class, [
            'method' => 'PUT',
            'url' => route('admin.user.partner.store', ['user_id' => $userId]),
        ]);
        $flag = 'partner';//用于区分表单页面的js
        return view('user.form', compact('form', 'sidebar', 'flag'));
    }

    public function storeApplication(Request $request)
    {
        $this->authorize('user-apply-edit');
        $userId = $request->input('user_id');

        $form = $this->form(ApplicationForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        $data['user_id'] = $userId;
        $data['status'] = ApplyPartner::STATUS_PASS;
        ApplyPartner::query()->create($data);
        User::query()->where('id', $userId)->update(['name' => $data['name']]);
        return redirect()->back()->with('success', "添加成功")->withInput();
    }

    public function editApplication($id, Request $request)
    {
        $this->authorize('user-apply-edit');
        $sidebar = $request->input('sidebar', 'apply');
        $upstream = $request->input('upstream', 'show');
        $apply = ApplyPartner::query()
            ->find($id);
        $form = $this->form(ApplicationForm::class, [
            'method' => 'POST',
            'url' => route('admin.user.partner.update', ['id' => $id, 'upstream' => $upstream]),
            'model' => $apply,
        ]);
        
        $flag = 'partner';//用于区分表单页面的js
        return view('user.form', compact('form', 'sidebar', 'flag'));
    }

    public function updateApplication($id, Request $request)
    {
        $this->authorize('user-apply-edit');
        $form = $this->form(ApplicationForm::class);
        $upstream = $request->input('upstream');

        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        $apply = ApplyPartner::query()->find($id);
        $apply->update($data);
        User::query()->where('id', $apply->user_id)->update(['name' => $data['name']]);
        if ($upstream == 'show') {
            return redirect()->route('admin.user.partner.application', ['id' => $apply->user_id]);
        } else {
            return redirect()->route('admin.user.partner.apply');
        }
    }

    public function partnerApplication()
    {
        $this->authorize('user-apply');
        $data = ApplyPartner::query()
            ->join('users', 'users.id', '=', 'apply_partners.user_id')
//            ->leftJoin('users as partner', 'partner.id', '=', 'apply_partners.partner_id')
            ->leftJoin('users as personal', 'personal.id', '=', 'apply_partners.personal_id')
            ->select('users.nickname', 'users.avatar', 'personal.name as personal', 'apply_partners.*')
            ->orderBy('apply_partners.created_at', 'desc')
            ->where('apply_partners.status', ApplyPartner::STATUS_INIT)
            ->paginate(20);
        foreach ($data as $value) {
            $value->image = OSS::instance()->getUrl($value->image);
            $value->id_card = OSS::instance()->getUrl($value->id_card_positive) . ";" . OSS::instance()->getUrl($value->id_card_back);
        }

        $sidebar = 'apply';
        return view('user.apply', compact('data', 'sidebar'));
    }

    public function passApplication($id, Request $request)
    {
        $this->authorize('user-apply-edit');
        $personalId = $request->input('personal_id');
        $apply = ApplyPartner::query()
            ->where('id', $id)
            ->where('status', ApplyPartner::STATUS_INIT)
            ->first();

        if (!empty($personalId)) {
            $data = [
                'status' => ApplyPartner::STATUS_PASS,
                'personal_id' => $personalId
            ];
        } else {
            $data = [
                'status' => ApplyPartner::STATUS_PASS,
            ];
        }
        $apply->update($data);
        $user = User::query()
            ->where('id', $apply->user_id)
            ->first();
        $user->name = $apply->name;
        $user->level = 2;
        $user->referrer_id = $user->id;
        $user->personal_id = $apply->personal_id;

        $user->save();
        return redirect()->route('admin.user.partner.apply');
    }

    public function refuseApplication($id, Request $request)
    {
        $this->authorize('user-apply-edit');
        $reason = $request->input('reason');
        ApplyPartner::query()
            ->where('id', $id)
            ->where('status', ApplyPartner::STATUS_INIT)
            ->update([
                'status' => ApplyPartner::STATUS_FAIL,
                'reason' => $reason
            ]);
        return redirect()->route('admin.user.partner.apply');
    }

    public function setReferrerCandidate($id)
    {
        $user = User::query()
            ->find($id);
        $user->save();
        return redirect()->back();
    }

    public function changeEmployeeIdentity()
    {

    }

    public function getPartnerApplication($id)
    {
        $this->authorize('user-apply');
        $apply = ApplyPartner::query()
            ->where('user_id', $id)
            ->where('status', ApplyPartner::STATUS_PASS)
            ->orderBy('created_at', 'desc')
            ->first();

        $user = User::query()->find($id);
        $referrer = collect();
        if (!is_null($apply)) {
            $apply->image = OSS::instance()->getUrl($apply->image);
            $apply->id_card = [
                OSS::instance()->getUrl($apply->id_card_positive),
                OSS::instance()->getUrl($apply->id_card_back)
            ];
            $referrer = User::query()->find($apply->personal_id);
        }
        $sidebar = 'index2';
        return view('user.application_show', compact('apply', 'user', 'referrer', 'sidebar'));
    }

    public function getMember($id, Request $request)
    {
        $this->authorize('user');
        $member = Member::query()
            ->paginate(30);
        $data = Member::query()->where('user_id', $id)->paginate(20);
        $shop = Shop::query()->whereIn('id', $data->pluck('shop_id')->all())->get()->keyBy('id');
        $sidebar = 'index1';
        return view('user.member', compact('sidebar', 'member', 'shop', 'data', 'id'));
    }

    public function createMember($id)
    {
        $this->authorize('user-member');//user-member-edit
        $shop = Shop::query()->get();
        $form = $this->form(UserMemberForm::class, [
            'method' => 'PUT',
            'url' => route('admin.user.member.store', ['id' => $id]),
        ], [
            'shop' => $shop->pluck('name', 'id')->all()
        ]);
        $sidebar = 'index1';
        return view('user.form', compact('sidebar', 'form'));
    }

    public function storeMember($id)
    {
        $this->authorize('user-member');//user-member-edit
        $form = $this->form(UserMemberForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        $data['quota'] = $data['quota'] * 100;
        $data['rebate'] = $data['rebate'] * 100;
        $data['user_id'] = $id;
        Member::query()
            ->create($data);

        return redirect()->route('admin.user.member', ['id' => $id]);
    }

    public function changeQuota($id, Request $request)
    {
        $this->authorize('user-member');//user-member-edit
        $quota = $request->input('quota');
        Member::query()
            ->where('id', $id)
            ->update([
                'quota' => $quota * 100
            ]);
        return redirect()->back();
    }

    public function delMember($id)
    {
        $this->authorize('user-member');//user-member-edit
        $member = Member::query()
            ->find($id);
        if ($member->rebate > 0) {
            return redirect()->back()->with('warning', '已经有解锁数据, 不能删除！');
        }
        $member->delete();
        return redirect()->back();
    }
}
